/***************************************************************************
*                                Serial.cs
*                            -------------------
*   begin                : May 1, 2002
*   copyright            : (C) The RunUO Software Team
*   email                : info@runuo.com
*
*   $Id: Serial.cs 4 2006-06-15 04:28:39Z mark $
*
***************************************************************************/

/***************************************************************************
*
*   This program is free software; you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation; either version 2 of the License, or
*   (at your option) any later version.
*
***************************************************************************/

using System;

namespace Server
{
    public struct Serial : IComparable, IComparable<Serial>
    {
        private readonly int m_Serial;

        private static Serial m_LastMobile = Zero;
        private static Serial m_LastItem = 0x40000000;

        public static Serial LastMobile
        {
            get
            {
                return m_LastMobile;
            }
        }
        public static Serial LastItem
        {
            get
            {
                return m_LastItem;
            }
        }

        public static readonly Serial MinusOne = new Serial(-1);
        public static readonly Serial Zero = new Serial(0);

        public static Serial NewMobile
        {
            get
            {
                while (World.FindMobile(m_LastMobile = (m_LastMobile + 1)) != null)
                {
                }

                return m_LastMobile;
            }
        }

        public static Serial NewItem
        {
            get
            {
                while (World.FindItem(m_LastItem = (m_LastItem + 1)) != null)
                {
                }

                return m_LastItem;
            }
        }

        private Serial(int serial)
        {
            this.m_Serial = serial;
        }

        public int Value
        {
            get
            {
                return this.m_Serial;
            }
        }

        public bool IsMobile
        {
            get
            {
                return (this.m_Serial > 0 && this.m_Serial < 0x40000000);
            }
        }

        public bool IsItem
        {
            get
            {
                return (this.m_Serial >= 0x40000000 && this.m_Serial <= 0x7FFFFFFF);
            }
        }

        public bool IsValid
        {
            get
            {
                return (this.m_Serial > 0);
            }
        }

        public override int GetHashCode()
        {
            return this.m_Serial;
        }

        public int CompareTo(Serial other)
        {
            return this.m_Serial.CompareTo(other.m_Serial);
        }

        public int CompareTo(object other)
        {
            if (other is Serial)
                return this.CompareTo((Serial)other);
            else if (other == null)
                return -1;

            throw new ArgumentException();
        }

        public override bool Equals(object o)
        {
            if (o == null || !(o is Serial))
                return false;

            return ((Serial)o).m_Serial == this.m_Serial;
        }

        public static bool operator ==(Serial l, Serial r)
        {
            return l.m_Serial == r.m_Serial;
        }

        public static bool operator !=(Serial l, Serial r)
        {
            return l.m_Serial != r.m_Serial;
        }

        public static bool operator >(Serial l, Serial r)
        {
            return l.m_Serial > r.m_Serial;
        }

        public static bool operator <(Serial l, Serial r)
        {
            return l.m_Serial < r.m_Serial;
        }

        public static bool operator >=(Serial l, Serial r)
        {
            return l.m_Serial >= r.m_Serial;
        }

        public static bool operator <=(Serial l, Serial r)
        {
            return l.m_Serial <= r.m_Serial;
        }

        /*public static Serial operator ++ ( Serial l )
        {
        return new Serial( l + 1 );
        }*/

        public override string ToString()
        {
            return String.Format("0x{0:X8}", this.m_Serial);
        }

        public static implicit operator int(Serial a)
        {
            return a.m_Serial;
        }

        public static implicit operator Serial(int a)
        {
            return new Serial(a);
        }
    }
}